
import java.util.Date;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.TimeUnit;


public class Chef implements Runnable {
        private Status status;
        private int id;
        private Restaurant restaurant;

        public synchronized Status getStatus() {
                return status;
        }

        @Override
        public void run() {
                ChefTeam chefTeam = restaurant.getChefTeam();
                Order order = null;
                Queue<Order> orders = chefTeam.getOrders();
                while (!Thread.interrupted()) {
                        synchronized (this) {
                                try {
                                        Logger.logWrite("" + new Date() + " " + this
                                                        + " waiting for orders" + "\n");
                                        while (restaurant.getChefTeam().getOrders().isEmpty()) {
                                                wait();
                                        }
                                        Thread.yield();
                                        synchronized (orders) {
                                                if (!orders.isEmpty()) {
                                                        order = orders.poll();
                                                        status = Status.WORKING;
                                                }
                                        }
                                } catch (InterruptedException e) {
                                        return;
                                }
                        }
                        Logger.logWrite("" + new Date() + " " + this + " picked up order "
                                        + order.getId() + "\n");
                        order.setDoer(this);
                        work(order);
                        Logger.logWrite("" + new Date() + " " + this
                                        + " notified appropriate " + order.getWaiter() + " "
                                        + " that " + order.getId() + " is ready" + "\n");
                        synchronized (order.getWaiter()) {
                                order.getWaiter().notify();
                        }
                        status = Status.IDLE;
                }
        }

        public Chef(int id, Restaurant restaurant) {
                super();
                this.id = id;
                this.restaurant = restaurant;
                this.status = Status.IDLE;
        }

        @Override
        public synchronized String toString() {
                return "Chief " + getId();
        }

        public synchronized void setId(int id) {
                this.id = id;
        }

        public synchronized int getId() {
                return id;
        }

        public synchronized void work(Order order) {
                Logger.logWrite("" + new Date() + " " + this
                                + " started working with order " + order.getId() + " "
                                + " for " + order.getWaiter() + "\n");
                try {
                        TimeUnit.MILLISECONDS.sleep((new Random()).nextInt(300) + 100);

                } catch (InterruptedException e) {
                        return;
                }
                Logger.logWrite("" + new Date() + " " + this
                                + " finshed working with order " + order.getId() + " "
                                + " for " + order.getWaiter() + "\n");
        }
}